<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
      0.与迭代器类似,生成器也支持'可关闭'的概念.
        拥有next()
        可选return() 提前终止迭代器
        可选throw()
     */

    /*
        1.return()
            return()方法会强制生成器进入关闭状态
            提供给return()方法的值,就是终止迭代器对象的值
     */
    function* generatorFn() {
        for (const x of [1, 2, 3]) {
            yield x;
        }
    }

    const g1 = generatorFn();
    console.log(g1)         // generatorFn {<suspended>}
    console.log(g1.return(4)) // {value:4,done:true}
    console.log(g1)         // generatorFn {<closed>}
    console.log(g1.next())  // {value:undefined,done:true}
    
    // 1.1 for-of循环(会忽略done:true的IteratorObject的value)
    function * generatorFn2() {
        for(const x of [1,2,3]){
            yield x;
        }
    }
    const g2 = generatorFn2();
    
    for(const x of g2){
        if(x>1){
            g2.return(4);
        }
        console.log(x)  // 1 2
    }
    
    /*
        2.throw()
            throw()方法会在暂停的时候讲一个错误注入到生成器对象中
            如果错误没有处理,生成器对象就会关闭
     */
    
    // 2.1没有处理的情况
    function * generatorFn3() {
        for(const x of [1,2,3]){
            yield x;
        }
    }
    const g3 = generatorFn3();
    console.log(g3) // generatorFn {<suspended>}
    try {
        g3.throw('foo')
    }catch (e) {
        console.log(e)  // foo
    }
    console.log(g3) // generatorFn {<closed>}
    
    
    // 2.2 来处理一下下下下下下
    function * generatorFn4() {
        for(const x of [1,2,3]){
            try{
                yield x;
            }catch (e) {
                console.log(e)
            }
        }
    }
    
    const g4 = generatorFn4();
    console.log(g4.next()) // {value:1,done:false}
    g4.throw('foo')         // foo
    console.log(g4.next())  // {value:3,done:false}
    
</script>
</body>
</html>